home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / frasrc19.zip / FRACTINT.C < prev    next >
C/C++ Source or Header  |  1995-03-04  |  18KB  |  571 lines

  1. /*
  2.     FRACTINT - The Ultimate Fractal Generator
  3.             Main Routine
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <time.h>
  10. #include <signal.h>
  11. #ifndef XFRACT
  12. #include <io.h>
  13. #include <dos.h>
  14. #include <stdarg.h>
  15. #else
  16. #include <varargs.h>
  17. #endif
  18. #include <ctype.h>
  19.  
  20. #include "prototyp.h"
  21. #include "fractype.h"
  22. #include "helpdefs.h"
  23.  
  24. struct videoinfo videoentry;
  25. int helpmode;
  26.  
  27. long timer_start,timer_interval;    /* timer(...) start & total */
  28. int    adapter;        /* Video Adapter chosen from list in ...h */
  29. char *fract_dir1="", *fract_dir2="";
  30.  
  31. #ifdef __TURBOC__
  32.  
  33. /* yes, I *know* it's supposed to be compatible with Microsoft C,
  34.    but some of the routines need to know if the "C" code
  35.    has been compiled with Turbo-C.  This flag is a 1 if FRACTINT.C
  36.    (and presumably the other routines as well) has been compiled
  37.    with Turbo-C. */
  38. int compiled_by_turboc = 1;
  39.  
  40. /* set size to be used for overlays, a bit bigger than largest (help) */
  41. unsigned _ovrbuffer = 54 * 64; /* that's 54k for overlays, counted in paragraphs */
  42.  
  43. #else
  44.  
  45. int compiled_by_turboc = 0;
  46.  
  47. #endif
  48.  
  49. /*
  50.    the following variables are out here only so
  51.    that the calcfract() and assembler routines can get at them easily
  52. */
  53.     int    active_system = 0;    /* 0 for DOS, WINFRAC for Windows */
  54.     int    dotmode;        /* video access method        */
  55.     int    textsafe2;        /* textsafe override from videotable */
  56.     int    oktoprint;        /* 0 if printf() won't work */
  57.     int    sxdots,sydots;        /* # of dots on the physical screen    */
  58.     int    sxoffs,syoffs;        /* physical top left of logical screen */
  59.     int    xdots, ydots;        /* # of dots on the logical screen     */
  60.     double    dxsize, dysize;     /* xdots-1, ydots-1        */
  61.     int    colors;         /* maximum colors available */
  62.     long    maxit;            /* try this many iterations */
  63.     int    boxcount;        /* 0 if no zoom-box yet     */
  64.     int    zrotate;        /* zoombox rotation        */
  65.     double    zbx,zby;        /* topleft of zoombox        */
  66.     double    zwidth,zdepth,zskew;    /* zoombox size & shape     */
  67.  
  68.     int    fractype;        /* if == 0, use Mandelbrot  */
  69.     char    stdcalcmode;        /* '1', '2', 'g', 'b'       */
  70.     long    creal, cimag;        /* real, imag'ry parts of C */
  71.     long    delx, dely;        /* screen pixel increments  */
  72.     long    delx2, dely2;        /* screen pixel increments  */
  73.         LDBL   delxx, delyy;           /* screen pixel increments  */
  74.         LDBL   delxx2, delyy2;         /* screen pixel increments  */
  75.     long    delmin;         /* for calcfrac/calcmand    */
  76.     double    ddelmin;        /* same as a double        */
  77.     double    param[MAXPARAMS];    /* parameters               */
  78.     double    potparam[3];        /* three potential parameters*/
  79.     long    fudge;            /* 2**fudgefactor        */
  80.     long    l_at_rad;        /* finite attractor radius  */
  81.     double    f_at_rad;        /* finite attractor radius  */
  82.     int    bitshift;        /* fudgefactor            */
  83.  
  84.     int    badconfig = 0;        /* 'fractint.cfg' ok?       */
  85.     int    diskisactive;        /* disk-video drivers flag  */
  86.     int    diskvideo;        /* disk-video access flag   */
  87.     int hasinverse = 0;
  88.     /* note that integer grid is set when integerfractal && !invert;    */
  89.     /* otherwise the floating point grid is set; never both at once     */
  90.     long    far *lx0, far *ly0;    /* x, y grid            */
  91.     long    far *lx1, far *ly1;    /* adjustment for rotate    */
  92.     /* note that lx1 & ly1 values can overflow into sign bit; since     */
  93.     /* they're used only to add to lx0/ly0, 2s comp straightens it out  */
  94.     double far *dx0, far *dy0;    /* floating pt equivs */
  95.     double far *dx1, far *dy1;
  96.     int    integerfractal;     /* TRUE if fractal uses integer math */
  97.  
  98.     /* usr_xxx is what the user wants, vs what we may be forced to do */
  99.     char    usr_stdcalcmode;
  100.     int    usr_periodicitycheck;
  101.     int    usr_distest;
  102.     char    usr_floatflag;
  103.  
  104.     int    viewwindow;        /* 0 for full screen, 1 for window */
  105.     float    viewreduction;        /* window auto-sizing */
  106.     int    viewcrop;        /* nonzero to crop default coords */
  107.     float    finalaspectratio;    /* for view shape and rotation */
  108.     int    viewxdots,viewydots;    /* explicit view sizing */
  109.  
  110.     HISTORY  far *history = NULL;
  111.     int maxhistory = 10;
  112.  
  113. /* variables defined by the command line/files processor */
  114. int    comparegif=0;            /* compare two gif files flag */
  115. int    timedsave=0;            /* when doing a timed save */
  116. int    resave_flag=0;            /* tells encoder not to incr filename */
  117. int    started_resaves=0;        /* but incr on first resave */
  118. int    save_system;            /* from and for save files */
  119. int    tabmode = 1;            /* tab display enabled */
  120.  
  121. /* for historical reasons (before rotation):         */
  122. /*    top    left  corner of screen is (xxmin,yymax) */
  123. /*    bottom left  corner of screen is (xx3rd,yy3rd) */
  124. /*    bottom right corner of screen is (xxmax,yymin) */
  125. double    xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* selected screen corners  */
  126. long    xmin, xmax, ymin, ymax, x3rd, y3rd;  /* integer equivs         */
  127. double    sxmin,sxmax,symin,symax,sx3rd,sy3rd; /* displayed screen corners */
  128. double    plotmx1,plotmx2,plotmy1,plotmy2;     /* real->screen multipliers */
  129.  
  130. int calc_status; /* -1 no fractal            */
  131.          /*  0 parms changed, recalc reqd   */
  132.          /*  1 actively calculating        */
  133.          /*  2 interrupted, resumable        */
  134.          /*  3 interrupted, not resumable   */
  135.          /*  4 completed            */
  136. long calctime;
  137.  
  138. int max_colors;                /* maximum palette size */
  139. int       zoomoff;            /* = 0 when zoom is disabled    */
  140. int       savedac;            /* save-the-Video DAC flag    */
  141. int browsing;                 /* browse mode flag */
  142. char file_name_stack[16][13]; /* array of file names used while browsing */
  143. int name_stack_ptr ;
  144. double toosmall;
  145. int  minbox;
  146. int no_sub_images;
  147. int autobrowse,doublecaution;
  148. char brwscheckparms,brwschecktype;
  149. char browsemask[13];
  150.  
  151. #define RESTART           1
  152. #define IMAGESTART        2
  153. #define RESTORESTART      3
  154. #define CONTINUE          4
  155.  
  156. static void check_samename(void)       
  157.    {
  158.       char drive[FILE_MAX_DRIVE];
  159.       char dir[FILE_MAX_DIR];
  160.       char fname[FILE_MAX_FNAME];
  161.       char ext[FILE_MAX_EXT];
  162.       char path[FILE_MAX_PATH];
  163.       splitpath(savename,drive,dir,fname,ext);
  164.       if(strcmp(fname,"fract001"))
  165.       {
  166.          makepath(path,drive,dir,fname,"gif");
  167.          if(access(path,0)==0)
  168.      exit(0);
  169.       }     
  170.    }
  171.  
  172. /* Do nothing if math error */
  173. static void my_floating_point_err(int sig)
  174. {
  175.    if(sig != 0)
  176.       overflow = 1;
  177. }
  178.  
  179. void main(int argc, char **argv)
  180. {
  181.    int     resumeflag;
  182.    int       kbdchar;            /* keyboard key-hit value    */
  183.    int       kbdmore;            /* continuation variable    */
  184.    char stacked=0;            /* flag to indicate screen stacked */
  185.  
  186.    /* this traps non-math library floating point errors */
  187.    signal( SIGFPE, my_floating_point_err );
  188.  
  189.    initasmvars();            /* initialize ASM stuff */
  190.    checkfreemem(0);
  191.    load_videotable(1); /* load fractint.cfg, no message yet if bad */
  192. #ifdef XFRACT
  193.    UnixInit();
  194. #endif
  195.    init_help();
  196.  
  197. restart:   /* insert key re-starts here */
  198.    autobrowse     = FALSE;
  199.    brwschecktype  = TRUE;
  200.    brwscheckparms = TRUE;
  201.    doublecaution  = TRUE;
  202.    no_sub_images = FALSE;
  203.    toosmall = 6;
  204.    minbox   = 3;
  205.    strcpy(browsemask,"*.GIF");
  206.    strcpy(browsename,"            ");
  207.    name_stack_ptr= -1; /* init loaded files stack */
  208.    if (fract_dir1==NULL) 
  209.        fract_dir1 = ".";
  210.    cmdfiles(argc,argv);     /* process the command-line */
  211.    dopause(0);            /* pause for error msg if not batch */
  212.    init_msg(0,"",NULL,0);  /* this causes getakey if init_msg called on runup */
  213.    checkfreemem(1);
  214.    if(debugflag==450 && initbatch==1)   /* abort if savename already exits */
  215.        check_samename();
  216. #ifdef XFRACT
  217.    initUnixWindow();
  218. #endif
  219.    memcpy(olddacbox,dacbox,256*3);    /* save in case colors= present */
  220.  
  221.    if (debugflag == 8088)         cpu =    86; /* for testing purposes */
  222.    if (debugflag == 2870 && fpu >= 287 ) fpu = 287; /* for testing purposes */
  223.    if (debugflag ==  870 && fpu >=  87 ) fpu =    87; /* for testing purposes */
  224.    if (debugflag ==   70)         fpu =     0; /* for testing purposes */
  225.    if (getenv("NO87")) fpu = 0;
  226.    fract_dir1 = getenv("FRACTDIR");
  227.    if (fract_dir1==NULL) {
  228.        fract_dir1 = ".";
  229.    }
  230. #ifdef SRCDIR
  231.    fract_dir2 = SRCDIR;
  232. #else
  233.    fract_dir2 = ".";
  234. #endif
  235.    if (fpu == 0)       iit = 0;
  236.    if (fpu >= 287 && debugflag != 72)    /* Fast 287 math */
  237.       setup287code();
  238.  
  239.    /* IIT math coprocessor chip logic */
  240.    if(iit == 0 && fpu)
  241.       if(IITCoPro())
  242.          iit = 3;  /* detect iit chip */
  243.    if(iit < 0) iit = 0;  /* user wants chip turned off */
  244.    if(iit>0)
  245.    {
  246.       if(F4x4Check())
  247.          iit = 2;    /* semaphore TSR is installed */
  248.       else if(iit == 3)
  249.          iit = 0;    /* we detetct chip but no tsr - don't use */
  250.       /* else user forced iit == 1 */
  251.    }
  252.  
  253.    adapter_detect();            /* check what video is really present */
  254.    if (debugflag >= 9002 && debugflag <= 9100) /* for testing purposes */
  255.       if (video_type > (debugflag-9000)/2)     /* adjust the video value */
  256.      video_type = (debugflag-9000)/2;
  257.  
  258.    diskisactive = 0;            /* disk-video is inactive */
  259.    diskvideo = 0;            /* disk driver is not in use */
  260.    setvideotext();            /* switch to text mode */
  261.    calc_status = -1;            /* no active fractal image */
  262.    savedac = 0;             /* don't save the VGA DAC */
  263.  
  264. #ifndef XFRACT
  265.    if (debugflag == 10000)        /* check for free memory */
  266.       showfreemem();
  267.  
  268.    if (badconfig < 0)            /* fractint.cfg bad, no msg yet */
  269.       bad_fractint_cfg_msg();
  270. #endif
  271.  
  272.    max_colors = 256;                    /* the Windows version is lower */
  273.    max_kbdcount=(cpu==386) ? 80 : 30;   /* check the keyboard this often */
  274.  
  275.    if (showfile && initmode < 0) {
  276.       intro();                /* display the credits screen */
  277.       if (keypressed() == ESC) {
  278.      getakey();
  279.      goodbye();
  280.      }
  281.       }
  282.  
  283.    browsing = FALSE;
  284.  
  285.    if (!functionpreloaded)
  286.       set_if_old_bif();
  287.    stacked = 0;
  288. restorestart:
  289.    if (colorpreloaded)
  290.       memcpy(dacbox,olddacbox,256*3);    /* restore in case colors= present */
  291.  
  292.    lookatmouse = 0;            /* ignore mouse */
  293.  
  294.    while (showfile <= 0) {        /* image is to be loaded */
  295.       char *hdg;
  296.       tabmode = 0;
  297.       if (!browsing )     /*RB*/
  298.       {
  299.       if (overlay3d) {
  300.      hdg = "Select File for 3D Overlay";
  301.      helpmode = HELP3DOVLY;
  302.      }
  303.       else if (display3d) {
  304.      hdg = "Select File for 3D Transform";
  305.      helpmode = HELP3D;
  306.      }
  307.       else {
  308.      hdg = "Select File to Restore";
  309.      helpmode = HELPSAVEREST;
  310.      }
  311.       if (showfile < 0 && getafilename(hdg,gifmask,readname) < 0) {
  312.      showfile = 1;             /* cancelled */
  313.      initmode = -1;
  314.      break;
  315.      }
  316.  
  317.        name_stack_ptr = 0; /* 'r' reads first filename for browsing */
  318.        strcpy(file_name_stack[name_stack_ptr],browsename);
  319.      }
  320.  
  321.       showfile = 0;
  322.       helpmode = -1;
  323.       tabmode = 1;
  324.       if(stacked)
  325.       {
  326.          discardscreen();
  327.          setvideotext();
  328.          stacked = 0;
  329.       }
  330.       if (read_overlay() == 0)         /* read hdr, get video mode */
  331.      break;              /* got it, exit */
  332.       showfile = -1;             /* retry */
  333.       }
  334.  
  335.    helpmode = HELPMENU;         /* now use this help mode */
  336.    tabmode = 1;
  337.    lookatmouse = 0;            /* ignore mouse */
  338.  
  339.    if ((overlay3d || stacked) && initmode < 0) {    /* overlay command failed */
  340.       unstackscreen();            /* restore the graphics screen */
  341.       stacked = 0;
  342.       overlay3d = 0;            /* forget overlays */
  343.       display3d = 0;            /* forget 3D */
  344.       if (calc_status > 0 && calc_status !=2)
  345.      calc_status = 0;
  346.       resumeflag = 1;
  347.       goto resumeloop;            /* ooh, this is ugly */
  348.       }
  349.  
  350.    savedac = 0;             /* don't save the VGA DAC */
  351. imagestart:                /* calc/display a new image */
  352.    if(stacked)
  353.    {
  354.       discardscreen();
  355.       stacked = 0;
  356.    }
  357. #ifdef XFRACT
  358.    usr_floatflag = 1;
  359. #endif
  360.    got_status = -1;            /* for tab_display */
  361.  
  362.    if (showfile)
  363.       if (calc_status > 0)        /* goto imagestart implies re-calc */
  364.      calc_status = 0;
  365.  
  366.    if (initbatch == 0)
  367.       lookatmouse = -PAGE_UP;        /* just mouse left button, == pgup */
  368.  
  369.    cyclelimit = initcyclelimit;     /* default cycle limit     */
  370.  
  371.  
  372.    adapter = initmode;            /* set the video adapter up */
  373.    initmode = -1;            /* (once)            */
  374.  
  375.    while (adapter < 0) {        /* cycle through instructions */
  376.       if (initbatch) {                /* batch, nothing to do */
  377.          initbatch = 4;            /* exit with error condition set */
  378.          goodbye();
  379.       }
  380.       kbdchar = main_menu(0);
  381.       if (kbdchar == INSERT) goto restart;    /* restart pgm on Insert Key */
  382.       if (kbdchar == DELETE)            /* select video mode list */
  383.      kbdchar = select_video_mode(-1);
  384.       if ((adapter = check_vidmode_key(0,kbdchar)) >= 0)
  385.      break;                 /* got a video mode now */
  386. #ifndef XFRACT
  387.       if ('A' <= kbdchar && kbdchar <= 'Z')
  388.      kbdchar = tolower(kbdchar);
  389. #endif
  390.       if (kbdchar == 'd') {                     /* shell to DOS */
  391.      setclear();
  392.      printf("\n\nShelling to DOS - type 'exit' to return\n\n");
  393.      shell_to_dos();
  394.      goto imagestart;
  395.      }
  396.  
  397. #ifndef XFRACT
  398.       if (kbdchar == '@' || kbdchar == '2') {    /* execute commands */
  399. #else
  400.       if (kbdchar == F2 || kbdchar == '@') {     /* We mapped @ to F2 */
  401. #endif
  402.      if ((get_commands() & 4) == 0) 
  403.         goto imagestart;
  404.      kbdchar = '3';                         /* 3d=y so fall thru '3' code */
  405.      }
  406. #ifndef XFRACT
  407.       if (kbdchar == 'r' || kbdchar == '3' || kbdchar == '#') {
  408. #else
  409.       if (kbdchar == 'r' || kbdchar == '3' || kbdchar == F3) {
  410. #endif
  411.      display3d = 0;
  412.      if (kbdchar == '3' || kbdchar == '#' || kbdchar == F3)
  413.         display3d = 1;
  414.          if(colorpreloaded)
  415.             memcpy(olddacbox,dacbox,256*3);    /* save in case colors= present */
  416.      setvideotext(); /* switch to text mode */
  417.      showfile = -1;
  418.      goto restorestart;
  419.      }
  420.       if (kbdchar == 't') {                     /* set fractal type */
  421.          julibrot = 0;
  422.      get_fracttype();
  423.      goto imagestart;
  424.      }
  425.       if (kbdchar == 'x') {                     /* generic toggle switch */
  426.      get_toggles();
  427.      goto imagestart;
  428.      }
  429.       if (kbdchar == 'y') {                     /* generic toggle switch */
  430.      get_toggles2();
  431.      goto imagestart;
  432.      }
  433.       if (kbdchar == 'z') {                     /* type specific parms */
  434.      get_fract_params(1);
  435.      goto imagestart;
  436.      }
  437.       if (kbdchar == 'v') {                     /* view parameters */
  438.      get_view_params();
  439.      goto imagestart;
  440.      }
  441.       if (kbdchar == 2) {                       /* ctrl B = browse parms*/
  442.      get_browse_params();
  443.      goto imagestart;
  444.      }
  445.       if (kbdchar == 'f') {                     /* floating pt toggle */
  446.      if (usr_floatflag == 0)
  447.         usr_floatflag = 1;
  448.      else
  449.         usr_floatflag = 0;
  450.      goto imagestart;
  451.      }
  452.       if (kbdchar == 'i') {                     /* set 3d fractal parms */
  453.      get_fract3d_params(); /* get the parameters */
  454.      goto imagestart;
  455.      }
  456.       if (kbdchar == 'g') {
  457.      get_cmd_string(); /* get command string */
  458.      goto imagestart;
  459.          }
  460.       /* buzzer(2); */                /* unrecognized key */
  461.       }
  462.  
  463.    zoomoff = 1;         /* zooming is enabled */
  464.    helpmode = HELPMAIN;     /* now use this help mode */
  465.    resumeflag = 0;  /* allows taking goto inside big_while_loop() */
  466. resumeloop:   
  467.    /* this switch processes gotos that are now inside function */
  468.    switch(big_while_loop(&kbdmore,&stacked,resumeflag))
  469.    {
  470.    case RESTART:
  471.       goto restart;
  472.    case IMAGESTART:
  473.       goto imagestart;
  474.    case RESTORESTART:
  475.       goto restorestart;
  476.    default:
  477.       break;   
  478.    }
  479. }
  480.  
  481. int check_key()
  482. {
  483.    int key;
  484.    if((key = keypressed()) != 0) {
  485.       if(key != 'o' && key != 'O') {
  486.      fflush(stdout);
  487.      return(-1);
  488.       }
  489.       getakey();
  490.       if (dotmode != 11)
  491.      show_orbit = 1 - show_orbit;
  492.    }
  493.    return(0);
  494. }
  495.  
  496. /* timer function:
  497.      timer(0,(*fractal)())        fractal engine
  498.      timer(1,NULL,int width)        decoder
  499.      timer(2)                encoder
  500.   */
  501. #ifndef XFRACT
  502. int timer(int timertype,int(*subrtn)(),...)
  503. #else
  504. int timer(va_alist)
  505. va_dcl
  506. #endif
  507. {
  508.    va_list arg_marker;    /* variable arg list */
  509.    char *timestring;
  510.    time_t ltime;
  511.    FILE *fp = NULL;
  512.    int out=0;
  513.    int i;
  514.    int do_bench;
  515.  
  516. #ifndef XFRACT
  517.    va_start(arg_marker,subrtn);
  518. #else
  519.    int timertype;
  520.    int (*subrtn)();
  521.    va_start(arg_marker);
  522.    timertype = va_arg(arg_marker, int);
  523.    subrtn = (int (*)())va_arg(arg_marker, int *);
  524. #endif
  525.  
  526.    do_bench = timerflag; /* record time? */
  527.    if (timertype == 2)     /* encoder, record time only if debug=200 */
  528.       do_bench = (debugflag == 200);
  529.    if(do_bench)
  530.       fp=dir_fopen(workdir,"bench","a");
  531.    timer_start = clock_ticks();
  532.    switch(timertype) {
  533.       case 0:
  534.      out = (*(int(*)(void))subrtn)();
  535.      break;
  536.       case 1:
  537.      i = va_arg(arg_marker,int);
  538.      out = (int)decoder((short)i); /* not indirect, safer with overlays */
  539.      break;
  540.       case 2:
  541.      out = encoder();         /* not indirect, safer with overlays */
  542.      break;
  543.       }
  544.    /* next assumes CLK_TCK is 10^n, n>=2 */
  545.    timer_interval = (clock_ticks() - timer_start) / (CLK_TCK/100);
  546.  
  547.    if(do_bench) {
  548.       time(<ime);
  549.       timestring = ctime(<ime);
  550.       timestring[24] = 0; /*clobber newline in time string */
  551.       switch(timertype) {
  552.      case 1:
  553.         fprintf(fp,"decode ");
  554.         break;
  555.      case 2:
  556.         fprintf(fp,"encode ");
  557.         break;
  558.      }
  559.       fprintf(fp,"%s type=%s resolution = %dx%d maxiter=%ld",
  560.       timestring,
  561.       curfractalspecific->name,
  562.       xdots,
  563.       ydots,
  564.       maxit);
  565.       fprintf(fp," time= %ld.%02ld secs\n",timer_interval/100,timer_interval%100);
  566.       if(fp != NULL)
  567.      fclose(fp);
  568.       }
  569.    return(out);
  570. }
  571.